package com.wenx.v3system.modular.cloud.controller;

import com.wenx.base.rest.BaseRestController;
import com.wenx.v3core.response.R;
import com.wenx.v3secure.annotation.RequiresPermissions;
import com.wenx.v3system.modular.cloud.domain.dto.SysDepartmentDto;
import com.wenx.v3system.modular.cloud.domain.dto.SysUserDto;
import com.wenx.v3system.modular.cloud.domain.query.DepartmentQuery;
import com.wenx.v3system.modular.cloud.domain.dto.DepartmentOperateDto;
import com.wenx.v3system.modular.cloud.domain.query.SysDepartmentQuery;
import com.wenx.v3system.modular.cloud.service.SysDepartmentRestService;
import com.wenx.v3secure.enums.SystemPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import static com.wenx.v3secure.annotation.RequiresPermissions.Logical.OR;

/**
 * 部门管理Controller
 * 提供部门的CRUD操作和组织架构管理
 * 基于Enhanced RBAC权限模型，支持权限验证和参数校验
 * 
 * @author wenx
 * @since 1.0.0
 */
@Slf4j
@Tag(name = "部门管理", description = "系统部门管理相关接口")
@RestController
@RequestMapping("/api/v3/sys/departments")
public class SysDepartmentController extends BaseRestController<SysDepartmentDto, SysDepartmentQuery, SysDepartmentRestService> {

    public SysDepartmentController(SysDepartmentRestService service) {
        super(service);
    }

    // ============= 基础CRUD操作 (继承自BaseRestController) =============

    /**
     * 分页查询部门列表
     */
    @Override
    @PostMapping("/page")
    @Operation(summary = "分页查询部门", description = "根据查询条件分页获取部门列表")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_READ_CODE}, logical = OR)
    public R page(@RequestBody @Valid SysDepartmentQuery query) {
        return R.ok(service.page(query));
    }

    /**
     * 根据ID获取部门详情
     */
    @Override
    @GetMapping("/get/{id}")
    @Operation(summary = "获取部门详情", description = "根据ID获取部门详细信息")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_READ_CODE}, logical = OR)
    public R get(@PathVariable Serializable id) {
        return R.ok(service.get(id));
    }

    /**
     * 创建部门
     */
    @Override
    @PostMapping("/add")
    @Operation(summary = "创建部门", description = "创建新的部门")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_MANAGE_CODE}, logical = OR)
    public R add(@RequestBody @Valid SysDepartmentDto departmentDto) {
        service.add(departmentDto);
        return R.ok();
    }

    /**
     * 更新部门
     */
    @Override
    @PutMapping("/update")
    @Operation(summary = "更新部门", description = "更新部门信息")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_MANAGE_CODE}, logical = OR)
    public R update(@RequestBody @Valid SysDepartmentDto departmentDto) {
        service.update(departmentDto);
        return R.ok();
    }

    /**
     * 删除部门
     */
    @Override
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除部门", description = "删除指定部门")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_MANAGE_CODE}, logical = OR)
    public R delete(@PathVariable  Serializable id) {
        Long departmentId = Long.valueOf(id.toString());
        
        // 检查是否有子部门
        List<SysDepartmentDto> children = service.getChildDepartments(departmentId);
        if (!children.isEmpty()) {
            return R.failed(null, "该部门下还有子部门，无法删除");
        }
        
        // 检查是否有成员
        List<Long> users = service.getDepartmentUsers(departmentId, false);
        if (!users.isEmpty()) {
            return R.failed(null, "该部门下还有成员，无法删除");
        }
        
        service.delete(departmentId);
        return R.ok();
    }

    // ============= 部门特有功能接口 =============

    /**
     * 获取部门树
     */
    @GetMapping("/tree")
    @Operation(summary = "获取部门树", description = "获取部门树形结构")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_READ_CODE}, logical = OR)
    public R getDepartmentTree(@Parameter(description = "父部门ID") @RequestParam(required = false) Long parentId) {
        List<SysDepartmentDto> tree = service.getDepartmentTree(parentId);
        return R.ok(tree);
    }

    /**
     * 获取部门成员列表
     */
    @PostMapping("/members")
    @Operation(summary = "获取部门成员", description = "分页查询部门成员列表")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_READ_CODE}, logical = OR)
    public R getMembers(@RequestBody @Valid DepartmentQuery query) {
        return R.ok(service.getDepartmentMembers(query));
    }

    /**
     * 添加部门成员
     */
    @PostMapping("/member/add")
    @Operation(summary = "添加部门成员", description = "向部门添加成员")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_MANAGE_CODE}, logical = OR)
    public R addMember(@RequestBody @Valid DepartmentOperateDto request) {
        service.addDepartmentMember(request);
        return R.ok();
    }

    /**
     * 移除部门成员
     */
    @PostMapping("/member/remove")
    @Operation(summary = "移除部门成员", description = "从部门移除成员")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_MANAGE_CODE}, logical = OR)
    public R removeMember(@RequestBody @Valid DepartmentOperateDto request) {
        service.removeDepartmentMember(request);
        return R.ok();
    }

    /**
     * 设置部门负责人
     */
    @PostMapping("/manager/set")
    @Operation(summary = "设置部门负责人", description = "设置部门的负责人")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_MANAGE_CODE}, logical = OR)
    public R setManager(@RequestBody @Valid DepartmentOperateDto request) {
        service.setDepartmentManager(request);
        return R.ok();
    }

    // ============= 检查和验证接口 =============

    /**
     * 检查部门编码是否存在
     */
    @GetMapping("/check-code")
    @Operation(summary = "检查部门编码", description = "检查部门编码是否已存在")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_READ_CODE}, logical = OR)
    public R checkDepartmentCode(
            @Parameter(description = "部门编码") @RequestParam String code, 
            @Parameter(description = "排除的部门ID") @RequestParam(required = false) String excludeId) {
        
        Long excludeIdLong = excludeId != null ? Long.valueOf(excludeId) : null;
        boolean exists = service.existsByCode(code, excludeIdLong);
        return R.ok(Map.of("exists", exists));
    }

    // ============= 部门管理操作接口 =============

    /**
     * 移动部门
     */
    @PostMapping("/move")
    @Operation(summary = "移动部门", description = "移动部门到新的父部门下")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_MANAGE_CODE}, logical = OR)
    public R move(@RequestBody @Valid DepartmentOperateDto request) {
        service.moveDepartment(request);
        return R.ok();
    }

    /**
     * 获取部门管理员用户列表
     */
    @GetMapping("/managers")
    @Operation(summary = "获取部门管理员用户", description = "获取具有部门管理员角色的用户列表")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_READ_CODE}, logical = OR)
    public R getDepartmentManagers() {
        List<SysUserDto> managers = service.getDepartmentManagers();
        return R.ok(managers);
    }

    // ============= 状态管理接口 =============

    /**
     * 启用部门
     */
    @PutMapping("/{id}/enable")
    @Operation(summary = "启用部门", description = "启用指定部门")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_MANAGE_CODE}, logical = OR)
    public R enableDepartment(@PathVariable String id) {
        service.enableDepartment(Long.valueOf(id));
        return R.ok();
    }

    /**
     * 禁用部门
     */
    @PutMapping("/{id}/disable")
    @Operation(summary = "禁用部门", description = "禁用指定部门")
    @RequiresPermissions(value = {SystemPermission.SYSTEM_ALL_CODE, SystemPermission.DEPT_MANAGE_CODE}, logical = OR)
    public R disableDepartment(@PathVariable  String id) {
        service.disableDepartment(Long.valueOf(id));
        return R.ok();
    }

}